/**
 * 20220119：finalized by jordia
 */
import ConvexSweepGeometry from "../shape/convex-sweep-geometry";
import AabbGeometry from "../shape/aabb-geometry";
import RayCastHit from "../shape/ray-cast-hit";
import Vec3 from "../common/vec3";
import Transform from "../common/transform";
import ProxyPair from "./proxy-pair";
import Method from "../common/method";

/**
 * 碰撞粗测基类
 */
export default class BroadPhase {
    constructor(type) {
        this._type = type;
        this._numProxies = 0;
        this._proxyList = null;
        this._proxyListLast = null;
        this._proxyPairList = null;
        this._incremental = false;
        this._testCount = 0;
        this._proxyPairPool = null;
        this._idCount = 0;
        this._convexSweep = new ConvexSweepGeometry();
        this._aabb = new AabbGeometry();
        this.identity = new Transform();
        this.zero = new Vec3();
        this.raycastHit = new RayCastHit();
        this._tb=new Float64Array(6);
        this._bv0=new Float64Array(3);
    }
    get testCount() {
        return this._testCount;
    }
    createProxy(userData,aabb) {
        return null;
    }
    destroyProxy(proxy) {
    }
    moveProxy(proxy,aabb,displacement) {
    }
    isOverlapping(proxy1,proxy2) {
        let o=proxy1.size,t=proxy2.size;
        return Method.boxIntersectsBox(o,t);
    }
    collectPairs() {
    }
    getProxyPairList() {
        return this._proxyPairList;
    }
    isIncremental() {
        return this._incremental;
    }
    rayCast(begin,end,callback) {
    }
    convexCast(convex,begin,translation,callback) {
    }
    aabbTest(aabb,callback) {
    }
    _setProxyPairList(){
        let first = this._proxyPairPool;
        if(first != null) {
            this._proxyPairPool = first._next;
            first._next = null;
        } else {
            first = new ProxyPair();
        }
        let pp = first;
        if(this._proxyPairList == null) {
            this._proxyPairList = pp;
        } else {
            pp._next = this._proxyPairList;
            this._proxyPairList = pp;
        }
        return pp;
    }
    _raycastTest(na,x1,y1,z1,x2,y2,z2){
        let rb=Method.setBox(x1,y1,z1,x2,y2,z2,this._tb);
        let tmp;
        if(!Method.boxIntersectsBox(rb,na)) {
            tmp = false;
        } else {
            let dx = x2 - x1, dy = y2 - y1, dz = z2 - z1;
            let adx = dx < 0 ? -dx : dx, ady = dy < 0 ? -dy : dy, adz = dz < 0 ? -dz : dz;
            let ptx = (na[3] - na[0]) * 0.5, pty = (na[4] - na[1]) * 0.5, ptz = (na[5] - na[2]) * 0.5;
            let cpx = x1 - (na[3] + na[0]) * 0.5, cpy = y1 - (na[4] + na[1]) * 0.5, cpz = z1 - (na[5] + na[2]) * 0.5;
            let tmp1, tmp2;
            let x = cpy * dz - cpz * dy;
            if(!((x < 0 ? -x : x) - (pty * adz + ptz * ady) > 0)) {
                let x = cpz * dx - cpx * dz;
                tmp2 = (x < 0 ? -x : x) - (ptz * adx + ptx * adz) > 0;
            } else {
                tmp2 = true;
            }
            if(!tmp2) {
                let x = cpx * dy - cpy * dx;
                tmp1 = (x < 0 ? -x : x) - (ptx * ady + pty * adx) > 0;
            } else {
                tmp1 = true;
            }
            tmp = !tmp1;
        }
        return tmp;
    }
    _setProxyList(numProxies,p,aabb){
        let _numProxies=numProxies+1;
        if(this._proxyList == null) {
            this._proxyList = p;
            this._proxyListLast = p;
        } else {
            this._proxyListLast._next = p;
            p._prev = this._proxyListLast;
            this._proxyListLast = p;
        }
        let pe=p.size,ae=aabb.elements;
        Method.copyElements(ae,pe,0,0,6);
        return _numProxies;
    }
}